#include <syscall.h>
#include <stdint.h>
#include <unistd.h>

static const long IGNORE = 0L;

static long invoke_syscall(long sysno, long arg0, long arg1, long arg2,
                           long arg3, long arg4)
{
    /* TODO: [p2-task3] implement invoke_syscall via inline assembly */
    long return_value = 0;
    asm volatile(
    "mv a7, a0\n\t"
    "mv a0, a1\n\t"
    "mv a1, a2\n\t"
    "mv a2, a3\n\t"
    "mv a3, a4\n\t"
    "mv a4, a5\n\t"
    
    "ecall"
    );
    
    asm volatile(
    "mv %0, a0\n\t"
    :"=r"(return_value)
    );

    return return_value;
}

void sys_yield(void)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_yield */
    invoke_syscall(SYSCALL_YIELD,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE);
}

void sys_move_cursor(int x, int y)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_move_cursor */
    invoke_syscall(SYSCALL_CURSOR,x,y,IGNORE,IGNORE,IGNORE);
}

void sys_write(char *buff)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_write */
    invoke_syscall(SYSCALL_WRITE,buff,IGNORE,IGNORE,IGNORE,IGNORE);
    
}

void sys_reflush(void)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_reflush */
    invoke_syscall(SYSCALL_REFLUSH,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE);
}

int sys_mutex_init(int key)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_mutex_init */
    return invoke_syscall(SYSCALL_LOCK_INIT,key,IGNORE,IGNORE,IGNORE,IGNORE);
}

void sys_mutex_acquire(int mutex_idx)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_mutex_acquire */
    invoke_syscall(SYSCALL_LOCK_ACQ,mutex_idx,IGNORE,IGNORE,IGNORE,IGNORE);
}

void sys_mutex_release(int mutex_idx)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_mutex_release */
    invoke_syscall(SYSCALL_LOCK_RELEASE,mutex_idx,IGNORE,IGNORE,IGNORE,IGNORE);
}

long sys_get_timebase(void)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_get_timebase */
    return invoke_syscall(SYSCALL_GET_TIMEBASE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE);
}

long sys_get_tick(void)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_get_tick */
    return invoke_syscall(SYSCALL_GET_TICK,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE);
}

void sys_sleep(uint32_t time)
{
    /* TODO: [p2-task3] call invoke_syscall to implement sys_sleep */
    invoke_syscall(SYSCALL_SLEEP,time,IGNORE,IGNORE,IGNORE,IGNORE);
}
// S-core

pid_t  sys_exec(int id, int argc, uint64_t arg0, uint64_t arg1, uint64_t arg2)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_exec for S_CORE */
    return invoke_syscall(SYSCALL_EXEC, id, argc, arg0, arg1, arg2);
}    

// A/C-core

// pid_t  sys_exec(char *name, int argc, char **argv)

// {

//     /* TODO: [p3-task1] call invoke_syscall to implement sys_exec */

// }





void sys_exit(void)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_exit */
    invoke_syscall(SYSCALL_EXIT, IGNORE, IGNORE, IGNORE, IGNORE, IGNORE);
}



int  sys_kill(pid_t pid)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_kill */
    return invoke_syscall(SYSCALL_KILL, pid, IGNORE, IGNORE, IGNORE, IGNORE);
}



int  sys_waitpid(pid_t pid)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_waitpid */

}





void sys_ps(void)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_ps */
    invoke_syscall(SYSCALL_PS, IGNORE, IGNORE, IGNORE, IGNORE, IGNORE);
}



pid_t sys_getpid()

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_getpid */

}



int  sys_getchar(void)

{

    /* TODO: [p3-task1] call invoke_syscall to implement sys_getchar */
    return invoke_syscall(SYSCALL_READCH, IGNORE, IGNORE, IGNORE , IGNORE , IGNORE);
}



int  sys_barrier_init(int key, int goal)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_barrier_init */

}



void sys_barrier_wait(int bar_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_barrie_wait */

}



void sys_barrier_destroy(int bar_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_barrie_destory */

}



int sys_condition_init(int key)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_condition_init */

}



void sys_condition_wait(int cond_idx, int mutex_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_condition_wait */

}



void sys_condition_signal(int cond_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_condition_signal */

}



void sys_condition_broadcast(int cond_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_condition_broadcast */

}



void sys_condition_destroy(int cond_idx)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_condition_destroy */

}



int sys_mbox_open(char * name)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_mbox_open */

}



void sys_mbox_close(int mbox_id)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_mbox_close */

}



int sys_mbox_send(int mbox_idx, void *msg, int msg_length)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_mbox_send */

}



int sys_mbox_recv(int mbox_idx, void *msg, int msg_length)

{

    /* TODO: [p3-task2] call invoke_syscall to implement sys_mbox_recv */

}

